import { ref, watch } from 'vue';
import { defineStore } from 'pinia';

const activeLayer = ref(null); // 当前标绘图层

export const usePlottingMapStore = defineStore('plottingMapStore', () => {
  const uuid = ref('');
  const position = ref('');
  const sceneTree = ref([]);
  const selectedNode = ref([]);
  const nodeSettings = ref({
    styleProperty: [],
    geomProperty: [],
  });
  const tempUuid = 111;

  const tempProperty = ref();
  watch(
    selectedNode,
    (newVal, oldVal) => {
      if (newVal[0] === oldVal[0]) return;
      if (newVal.length === 0) {
        document.plotting.setEditingNodeById(null, null);
      } else {
        const nodeId = newVal[0];
        const layer = findParentById(nodeId);
        const layerId = layer !== null ? layer.id : null;
        document.plotting.setEditingNodeById(layerId, nodeId);
      }
    },
    { deep: true },
  );

  watch(
    activeLayer,
    (newVal) => {
      document.plotting.setActiveLayerById(newVal);
    },
    { deep: true },
  );
  function addScene(id) {
    sceneTree.value.push({
      id,
      label: id,
      type: 'scene',
      selectable: false,
      children: [],
    });
    return true;
  }

  function addLayer(sceneId, layerId, layerName) {
    const scene = sceneTree.value.find((sceneItem) => sceneItem.id === sceneId);
    if (scene) {
      scene.children?.push({
        id: layerId,
        label: layerName,
        type: 'layer',
        selectable: false,
        children: [],
      });
      return true;
    }
    return false;
  }

  function addNode(layerId, nodeId) {
    const layer = findNodeById(layerId);
    if (layer) {
      layer.children?.push({
        id: nodeId,
        label: nodeId,
        uuid: tempUuid,
        property: tempProperty.value,
        type: 'node',
      });
      return true;
    }
    return false;
  }

  // eslint-disable-next-line max-params
  function addNodeWithParams(layerId, nodeId, nodeName, x, y) {
    const layer = findNodeById(layerId);
    if (layer) {
      layer.children?.push({
        id: nodeId,
        label: nodeId,
        type: 'node',
        name: nodeName,
        lon: x,
        lat: y,
      });
      return true;
    }
    return false;
  }

  function updateNode(nodeId, value) {
    const node = findNodeById(nodeId);
    if (node) {
      node.id = value;
      node.label = value;
    }
  }

  function deleteNode(id) {
    return sceneTree.value.filter((node) => {
      if (node.id === id) {
        return false;
      }
      if (node.children) {
        node.children = deleteNode(id);
      }
      return true;
    });
  }

  function setSelectedNode(id) {
    selectedNode.value = id ? [id] : [];
  }

  function applyAttribChange(group, name, value) {
    // console.log(group, name, value);
    if (group === 'style') {
      document.scene_event_listener.DrawingPropertyChanged(name, value);
    } else if (group === 'geometry') {
      document.scene_event_listener.GeometryPropertyChanged(name, value);
    }
  }

  function findNodeById(id) {
    let result = null;
    function search(node) {
      if (node.id === id) {
        result = node;
        return;
      }
      node.children?.forEach(search);
    }
    sceneTree.value.forEach(search);
    return result;
  }

  function findNodeByUuid(uuid) {
    let result = null;
    function search(node) {
      if (node.uuid === uuid) {
        result = node;
        return;
      }
      node.children?.forEach(search);
    }
    sceneTree.value.forEach(search);
    return result;
  }

  function findParentById(id) {
    let parentNode = null;
    function search(node, parent) {
      if (node.id === id) {
        parentNode = parent;
        return;
      }
      node.children?.forEach((child) => search(child, node));
    }
    sceneTree.value.forEach((node) => search(node, null));
    return parentNode;
  }

  function getAllNodes(id) {
    const allNodes = [];
    let foundNode = null;
    const visited = new Set();

    function search(node) {
      if (visited.has(node.id)) return;
      visited.add(node.id);

      if (node.type === 'node') {
        allNodes.push(node);
      }

      if (id && node.id === id) {
        foundNode = node;
        return;
      }
      node.children?.forEach(search);
    }

    sceneTree.value.forEach(search);
    return id ? foundNode : allNodes;
  }
  // 悬浮事件
  function sendMessage(id) {
    const node = this.findNodeById(id);
    // console.log("nodeid", id);
    // console.log(node.property);
    window.$wujie?.bus.$emit('mapServerHoverEntity', node.property);
  }

  return {
    uuid,
    position,
    sceneTree,
    selectedNode,
    nodeSettings,
    activeLayer,
    addScene,
    addLayer,
    updateNode,
    deleteNode,
    addNode,
    addNodeWithParams,
    setSelectedNode,
    applyAttribChange,
    getAllNodes,
    findParentById,
    findNodeById,
    findNodeByUuid,
    tempUuid,
    tempProperty,
    sendMessage,
  };
});
